package cn.sh.ideal.yedis.builder;

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import cn.sh.ideal.yedis.util.Assert;
import cn.sh.ideal.yedis.util.StringUtil;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPoolConfig;

/**
 * redis cluster 客户端builder
 * Created by wyy
 */
public class RedisClusterBuilder extends BaseBuilder<JedisCluster>{
	/**
	 * 节点定位重试次数:默认3次
	 */
	private int maxRedirections = 5;
	
	public RedisClusterBuilder() {};
	
	public RedisClusterBuilder(String clusters) {
		this.nodeStr = clusters;
	}
	
	public RedisClusterBuilder(String clusters,JedisPoolConfig poolConfig) {
		this.nodeStr = clusters;
		this.poolConfig = poolConfig;
	}
	
	

	public JedisCluster build() {
		if (pool == null) {
			while (true) {
				try {
					LOCK.tryLock(10, TimeUnit.SECONDS);
					if (pool == null) {
						Assert.notEmpty(nodeStr, "cluster info must not be empty");

						Set<HostAndPort> nodeList = new HashSet<HostAndPort>();
						String[] nodeArray = nodeStr.split(SEPERATOR_NODE);
						for (String node : nodeArray) {
							String[] ipAndPort = node.split(SEPERATOR_IP_PROT);
							if (ipAndPort.length < 2) {
								continue;
							}
							String ip = ipAndPort[0];
							int port = Integer.parseInt(ipAndPort[1]);
							nodeList.add(new HostAndPort(ip, port));
						}

						if (StringUtil.isEmpty(password)) {
							pool = new JedisCluster(nodeList, timeout, soTimeout, maxRedirections, poolConfig);
						} else {
							pool = new JedisCluster(nodeList, timeout, soTimeout, maxRedirections, password, poolConfig);
						}

						return pool;
					}
				} catch (Throwable e) {
					logger.error(e.getMessage(), e);
					break;
				} finally {
					LOCK.unlock();
				}
			}
		} 
		
		return pool;
	}

	/**
	 * 节点定位重试次数:默认5次
	 */
	public RedisClusterBuilder setMaxRedirections(final int maxRedirections) {
		this.maxRedirections = maxRedirections;
		return this;
	}

}
